<template>
  <page-view class="page-view" :title="false">
    <div slot="headerContent">
      <a-breadcrumb class="s-breadcrumb">
        <a-breadcrumb-item>资产管理</a-breadcrumb-item>
        <a-breadcrumb-item><a @click="goback">出入库管理</a></a-breadcrumb-item>
        <a-breadcrumb-item>出入库管理</a-breadcrumb-item>
      </a-breadcrumb>
    </div>

    <a-card class="s-card">
      <a-spin :spinning="sending">

        <a-form-item class="filter">
          <a-row class="header-container ">
            <a-col v-for="({ key, label }) in headerData" :key="key" :lg="12" :sm="24">
              <a-form-item :label="label" v-bind="formItemLayout" class="label-width-auto">
                <div class="textOverflow" :title="orderData[key]">
                  <span v-if="key !== 'createdTime'">{{ orderData[key] }}</span>
                  <span v-else>{{ orderData[key] ? $moment(orderData[key]).format('YYYY年MM月DD日') : '无' }}</span>
                </div>
              </a-form-item>
            </a-col>
            <a-col :lg="12" :sm="24">
              <a-form-item v-bind="formItemLayout">
                <span class="primary-link" @click="checkPDF(orderData)">关联表单查看</span>
              </a-form-item>
            </a-col>
          </a-row>
        </a-form-item>

        <div class="table-container">
          <a-table
            class="s-table"
            bordered
            row-key="id"
            :locale="{ emptyText: '暂无数据' }"
            :pagination="false"
            :columns="$get(orderData, 'stockType', '入库') === '入库' ? putCloumns : outCloumns"
            :data-source="list"
          >
            <template slot="qtyStatus" slot-scope="item">
              <span>{{ item.actualQuantity > item.stockQty ? '不足' : '充足' }}</span>
            </template>

            <template slot="actualQuantity" slot-scope="text,item">
              <a-input-number v-if="item.editable" ref="outQtyInput" v-model="tempNum" :min="0" :max="item.stockQty" />
              <span v-else>{{ text }}</span>
            </template>

            <template slot="effectiveTime" slot-scope="item">
              <div style="width: 82px; display: inline-block; word-break: break-all">
                <!-- <a-input v-if="item.editable" v-model="item.effectiveTime" style="width: 100%;" @click="pickDates(item.k)" /> -->
                <span :title="item.effectiveTime">{{ item.effectiveTime || '/' }}</span>
              </div>
            </template>

            <template slot="action" slot-scope="item">
              <!-- 出库 -->
              <div v-if="$get(orderData, 'stockType', '入库') === '出库'" class="action-container">
                <!-- 修改出仓 -->
              <!-- <div v-if="!item.editable">
                <span v-if="item.actualQuantity > item.stockQty" class="primary-link" @click="handleEdit(item)">修改出仓</span>
              </div>
              <div v-else>
                <span class="success-link" @click="handleSave(item)">保存</span>
                <span class="danger-link" @click="handleCancel(item)">取消</span>
              </div> -->
                <!-- 修改出仓 foot -->
              </div>
              <!-- 出库 foot -->

              <div v-else class="action-container">
                <span v-if="!item.editable" class="primary-link" style="padding-right: 0;" @click="pickDates(item.k)">设置有效期</span>
                <div v-else>
                  <span class="success-link" @click="handleSave(item)">保存</span>
                  <span class="danger-link" @click="handleCancel(item)">取消</span>
                </div>
                <a-dropdown>
                  <a-menu v-show="!item.editable" slot="overlay">
                    <a-menu-item v-if="!item.goodsId" @click="clickMatch(item)">匹配系统物品</a-menu-item>
                    <a-menu-item v-if="!item.goodsId" class="success-color" @click="clickAdd(item)">新增物品</a-menu-item>
                    <a-menu-item v-if="/0/.test(item.isPut)" class="primary-color" @click="clickUndo(item)">无需入库</a-menu-item>
                    <a-menu-item v-else-if="/1/.test(item.isPut)" class="primary-color" @click="clickUndo(item, 0)">取消无需入库</a-menu-item>
                  </a-menu>
                  <span v-show="!item.editable" class="primary-link">操作 ></span>
                </a-dropdown>
              </div>
            </template>
          </a-table>
        </div>

        <div class="table-container">
          <a-table
            class="s-table"
            bordered
            row-key="id"
            :locale="{ emptyText: '暂无数据' }"
            :pagination="false"
            :columns="columns2"
            :data-source="$get(orderData, 'approvalVoList', [])"
          />
        </div>

        <div class="button-container">
          <a-button :loading="sending" class="primary-btn" @click="handleSubmit">{{ $get(orderData, 'stockType', '入库') }}</a-button>
          <a-button @click="goback">返回</a-button>
        </div>

      </a-spin>
    </a-card>

    <PDFModal
      :url="url"
      :visible="showPDF"
      :title="$get(orderData, 'stockType', '入库') === '出库' ? '领料申请单' : '物品申购单'"
      :extra-text="`${$get(orderData, 'stockType', '入库') === '出库' ? '申领' : '申购'}状态：${statusMaps[$get(orderData, 'status') || -1] || '暂无'}`"
      @cancel="showPDF = false"
    />

    <CalendarPicker
      :visible="showPicker"
      :default-dates="($get(list, `${targetIndex}.effectiveTime`, '') || '').split(',').filter(i => i)"
      @ok="handleOk"
      @cancel="showPicker = false"
    />

    <a-modal
      :visible="showAdd"
      title="新增物品"
      width="800px"
      centered
      @cancel="showAdd = false"
    >
      <add-item
        v-if="showAdd"
        ref="addItem"
        :form-item-layout="formItemLayout"
        :sending="sending"
        :item-data="tempItem"
        :disabled-keys="['name', 'quantity']"
        @sendingChange="sendingChange"
        @submit="handleAdd"
        @cancel="showAdd = false"
      />
      <template slot="footer">
        <a-button class="danger-btn-border" @click="showAdd = false">取消</a-button>
        <a-button :loading="sending" class="success-btn" @click="handleModal">确定</a-button>
      </template>
    </a-modal>

    <a-modal v-model="showSetTime" title="设置领取时间" centered>
      <a-form-item label="请设置物品领取时间段">
        <a-range-picker v-model="range" allow-clear :placeholder="['开始日期', '结束日期']" :disabled-date="disabledDate" />
      </a-form-item>
      <template slot="footer">
        <a-button @click="showSetTime = false">取消</a-button>
        <a-button class="primary-btn" :loading="sending" @click="submit">确定</a-button>
      </template>
    </a-modal>

    <!-- 匹配系统物品弹窗 -->

    <a-modal v-model="showMatch" title="匹配系统物品" centered>
      <div class="match-item-container">
        <div class="item-label">匹配物品：</div>
        <a-cascader
          v-model="matchItemData"
          class="item-cascader"
          :options="typeCascaderData"
          placeholder="请选择物品，或输入关键字进行搜索"
          :show-search="{ filter: itemSearchFilter }"
          :field-names="{ label: 'name', value: 'id', children: 'children', disabled: 'disabled' }"
        />
      </div>
      <template slot="footer">
        <a-button @click="showMatch = false">取消</a-button>
        <a-button class="primary-btn" :loading="sending" @click="handleMatchItem">确定</a-button>
      </template>
    </a-modal>
    <!-- 匹配系统物品弹窗 foot -->

    <!-- 无需入库弹窗 -->
    <a-modal
      v-model="showCheckUndo"
      title="确认"
      centered
    >
      <div class="ant-modal-confirm-body">
        <a-icon type="exclamation-circle" theme="filled" class="anticon anticon-question-circle" style="color: #faad14" />
        <div class="ant-modal-confirm-title">请确认该物品无需进行入库操作！</div>
        <div class="ant-modal-confirm-content alarm-color">确认后，本单进行入库时，该物品将不进行入库。</div>
      </div>
      <div slot="footer">
        <a-button @click="showCheckUndo = false">取消</a-button>
        <a-button class="primary-btn" :loading="sending" @click="updateItem()">确定</a-button>
      </div>
    </a-modal>
    <!-- 无需入库弹窗 foot -->

  </page-view>
</template>

<script>
import { mapState } from 'vuex'
import { PageView, STable, PDFModal, CalendarPicker, AddItem } from '@/components'

const headerData = [
  { label: '库存类型', key: 'stockType' },
  { label: '库存申请状态', key: 'statusName' },
  { label: '申请日期', key: 'createdTime' },
  { label: '申请部门', key: 'deptName' },
  { label: '申请人', key: 'userName' }
]
const columns2 = [
  { title: '入库流程', align: 'center', dataIndex: 'attr' },
  { title: '操作人', align: 'center', dataIndex: 'userName' },
  { title: '操作人身份', align: 'center', dataIndex: 'userId' },
  { title: '状态变化', align: 'center', dataIndex: 'statusName' },
  { title: '时间', align: 'center', dataIndex: 'changeTime' }
]
const statusMaps = {
  0: '待处理',
  1: '已处理',
  2: '不通过',
  3: '已取消',

  4: '待处理',
  6: '待领取',
  8: '已完成',
  9: '已失效',
  11: '已撤销'
}

export default {
  name: 'Handle',
  components: { PageView, STable, PDFModal, CalendarPicker, AddItem },
  inject: ['formItemLayout'],
  props: {
    id: {
      type: [String, Number],
      default: ''
    },
    applyType: {
      type: [String, Number],
      default: ''
    }
  },

  validate ({ params }) { return Boolean(params.id && params.applyType) },

  async fetch ({ $axios, store, app }) {
    const { $get } = store
    store.dispatch('property/getItemTypes')
    const list = []
    if (!$get(store, 'state.basic.deptList.length')) list.push({ fn: app.$departmentListFunc })
    if (!$get(store, 'state.basic.areaList.length')) list.push({ fn: app.$areaListFunc })
    await app.$requestList(list)
    store.dispatch('basic/setDeptArea')
  },

  async asyncData ({ app, $axios, params }) {
    const { id, applyType } = params
    const { $get, $moment } = app
    const orderData = await $axios.get(`api/assetsApply/${id}/-999999`)
      .then(res => $get(res, 'data.data', {}))
      .catch(e => ({}))
    orderData.statusName = $get(statusMaps, orderData.status, '暂无')
    if (!orderData.approvalVoList) orderData.approvalVoList = []
    orderData.approvalVoList.forEach(i => {
      const { createdTime, status } = i
      const arr = ['userName', 'userId']
      arr.forEach(k => { if (!i[k]) Object.assign(i, { [k]: '暂无' }) })
      Object.assign(i, {
        changeTime: createdTime ? $moment(createdTime).format('YYYY.MM.DD') : '暂无',
        statusName: $get(statusMaps, status, '暂无')
      })
    })

    const itemList = await $axios.post('api/assetsGoods/query', { pageNum: -1 })
      .then(res => $get(res, 'data.data.dataList', []))
      .catch(e => [])

    const list = await $axios.post('api/assetsApplyDetail/query', { pageNum: -1, applyId: id / 1, isStock: 1 }).then(res => {
      const data = $get(res, 'data.data.dataList', []).map((i, k) => {
        ['unit', 'model'].forEach(key => { if (!i[key]) Object.assign(i, { [key]: '暂无' }) })
        return Object.assign(i, { k: k + 1 })
      })
      return data
    }).catch(e => [])

    columns2[0].title = `${applyType}流程`

    return { orderData, list, itemList }
  },

  data () {
    return {
      headerData,
      statusMaps,

      showAdd: false,
      tempItem: {},
      sending: false,

      putCloumns: [
        { title: '序号', width: '8%', align: 'center', dataIndex: 'k' },
        { title: '物品名称', width: '18%', align: 'center', dataIndex: 'name' },
        { title: '规格型号', width: '10%', align: 'center', dataIndex: 'model' },
        { title: '单位', width: '8%', align: 'center', dataIndex: 'unit' },
        { title: '入库数量', width: '10%', align: 'center', dataIndex: 'quantity' },
        { title: '备注', width: '24%', align: 'center', dataIndex: 'remark' },
        { title: '有效日期', width: '82px', align: 'center', scopedSlots: { customRender: 'effectiveTime' }},
        { title: '操作', width: '186px', align: 'center', scopedSlots: { customRender: 'action' }}
      ],
      outCloumns: [
        { title: '物品名称', align: 'center', dataIndex: 'name' },
        { title: '规格', align: 'center', dataIndex: 'model' },
        { title: '申请数量', align: 'center', dataIndex: 'quantity' },
        { title: '审批数量', align: 'center', dataIndex: 'actualQuantity' },
        { title: '库存数', align: 'center', dataIndex: 'stockQty' },
        { title: '库存状态', align: 'center', scopedSlots: { customRender: 'qtyStatus' }},
        { title: '操作', align: 'center', scopedSlots: { customRender: 'action' }}
      ],
      columns2,

      tempNum: 0,

      showPDF: false,
      modalTitle: '',
      modalText: '',
      url: '',
      fileName: '',

      showPicker: false,
      targetIndex: -1,

      showSetTime: false,
      range: [],

      showCheckUndo: false,
      isPut: 1,

      showMatch: false,
      matchItemData: undefined
    }
  },

  computed: {
    ...mapState({
      typeCascaderData (state) {
        const { $get, itemList } = this
        const firTypes = state.property.itemFirTypeList
        const maps = state.property.itemSecTypeListMaps
        const itemMaps = {}

        itemList.forEach(i => {
          if (!itemMaps[i.firId]) itemMaps[i.firId] = []
          if (!itemMaps[i.firId][i.secId]) itemMaps[i.firId][i.secId] = []
          itemMaps[i.firId][i.secId].push(i)
        })

        const arr = firTypes.map(i => {
          const children = maps[i.id] || []
          children.forEach(o => {
            const child = $get(itemMaps, `${i.id}.${o.id}`, [])
            const data = { children: child }
            if (!child.length) data.disabled = true
            Object.assign(o, data)
            return o
          })
          const data = { children }
          if (!children.length) data.disabled = true
          return Object.assign({}, i, data)
        })
        console.log('arr', arr)
        return arr
      }
    })
  },

  watch: {
    list (arr) {
      arr.forEach((i, k) => Object.assign(i, { no: k + 1 }))
    },

    showPicker (bool) {
      if (!bool) this.targetIndex = -1
    },

    showAdd (bool) {
      if (!bool) this.tempItem = {}
    }
  },

  methods: {
    // 搜索物品
    itemSearchFilter (value, path) {
      console.log(value, path)
      return path.some(
        option => option.name.toLowerCase().indexOf(value.toLowerCase()) > -1
      )
    },

    // 匹配系统物品
    async handleMatchItem () {
      if (this.sending) return false
      const { matchItemData = [], $message, tempItem = {}, $axios, $get, getList } = this
      $message.destroy()
      const goodsId = matchItemData[2]
      const { id } = tempItem
      if (!id) {
        $message.error('错误：申请id为空，请刷新后重试')
        return false
      }
      if (!goodsId) {
        $message.error('请选择匹配物品')
        return false
      }
      this.sending = true
      const res = await $axios.post(`api/assetsApplyDetail/updateGoodsDetail/${id}/${goodsId}`, {})
        .then(res => res)
        .catch(e => false)
      await getList()
      this.sending = false
      if ($get(res, 'data.code') !== '000000') {
        $message.error($get(res, 'data.mesg', '请稍后再试'))
        return false
      } else $message.success('匹配成功')
      this.showMatch = false
    },

    // 点击匹配系统物品
    clickMatch (item) {
      this.matchItemData = undefined
      this.tempItem = item
      this.showMatch = true
    },

    // 确认无需入库，更新物品
    async updateItem () {
      const { id, remark } = this.tempItem
      if (!id || this.sending) {
        this.showCheckUndo = false
        return false
      }
      const { $message, $axios, $get, getList, isPut } = this
      $message.destroy()
      this.sending = true
      const params = { isPut }
      if (isPut) {
        params.remark = `${remark || ''}${remark ? '，' : ''}无需入库`
      } else {
        params.remark = remark.replace(/\，无需入库$/, '')
      }
      const res = await $axios.put(`api/assetsApplyDetail/${id}`, params).then(res => res).catch(e => false)

      await getList()

      this.sending = false
      this.showCheckUndo = false
      this.tempItem = {}
      if ($get(res, 'data.code') !== '000000') {
        $message.error($get(res, 'data.mesg', '请稍后再试'))
        return false
      }
      $message.success('操作成功')
    },

    // 点击无需入库
    clickUndo (item, isPut = 1) {
      this.isPut = isPut
      this.tempItem = item
      this.showCheckUndo = true
    },

    // 更新申请单数据
    getList () {
      const { $get, $axios, list } = this
      return new Promise((resolve, reject) => {
        $axios.post('api/assetsApplyDetail/query', { pageNum: -1, applyId: this.id / 1, isStock: 1 }).then(res => {
          const data = $get(res, 'data.data.dataList', []).map((i, k) => {
            ['unit', 'model'].forEach(key => { if (!i[key]) Object.assign(i, { [key]: '暂无' }) })
            return Object.assign(i, { k: k + 1 })
          })
          list.splice(0, list.length, ...data)
          resolve()
        }).catch(e => {
          list.splice(0, list.length)
          resolve()
        })
      })
    },

    disabledDate (c) {
      return c && c < this.$moment().add(-1, 'day').endOf('day')
    },

    handleModal () {
      const dom = this.$refs.addItem
      dom && dom.handleSubmit && dom.handleSubmit()
    },

    sendingChange (v) {
      this.$toggleSending(v)
    },

    async handleAdd (values) {
      const { id, tempItem, $axios, $message, $get, $moment } = this
      const res = await $axios.post(`api/assetsApplyDetail/addGoods/${tempItem.id}`, values).then(res => res).catch(e => false)
      $message.destroy()
      if ($get(res, 'data.code') !== '000000') return $message.error($get(res, 'data.mesg', '请稍后再试'))
      $message.info('新增成功')
      const orderData = await $axios.get(`api/assetsApply/${id}/-999999`)
        .then(res => $get(res, 'data.data', {}))
        .catch(e => ({}))
      orderData.statusName = $get(statusMaps, orderData.status, '暂无')
      if (!orderData.approvalVoList) orderData.approvalVoList = []
      orderData.approvalVoList.forEach(i => {
        const { createdTime, status } = i
        const arr = ['userName', 'userId']
        arr.forEach(k => { if (!i[k]) Object.assign(i, { [k]: '暂无' }) })
        Object.assign(i, {
          changeTime: createdTime ? $moment(createdTime).format('YYYY.MM.DD') : '暂无',
          statusName: $get(statusMaps, status, '暂无')
        })
      })

      const list = await $axios.post('api/assetsApplyDetail/query', { pageNum: -1, applyId: id / 1, isStock: 1 }).then(res => {
        const data = $get(res, 'data.data.dataList', []).map((i, k) => {
          ['unit', 'model'].forEach(key => { if (!i[key]) Object.assign(i, { [key]: '暂无' }) })
          return Object.assign(i, { k: k + 1 })
        })
        return data
      }).catch(e => [])
      this.list.splice(0, this.list.length, ...list)
      Object.assign(this.orderData, orderData)
      // Object.assign(this, { list, orderData })
      this.showAdd = false
    },

    clickAdd (item) {
      Object.assign(this.tempItem, item)
      this.showAdd = true
    },

    handleOk (effectiveTime = []) {
      effectiveTime = effectiveTime.join(',')
      this.showPicker = false
      const target = this.list[this.targetIndex]
      Object.assign(target, { effectiveTime })
    },

    pickDates (index = -1) {
      if (index < 0) return false
      this.targetIndex = index - 1
      this.showPicker = true
    },

    handleSubmit () {
      const { submit, orderData, $get, $confirm, $message, list } = this
      const { stockType } = orderData

      $message.destroy()

      if (orderData.stockType === '出库') {
      // 检验出库是否需要修改库存
        const someLack = list.some(i => i.actualQuantity > i.stockQty)
        // if (someLack) return $message.error('物品库存不足，请修改出仓')
        if (someLack) return $message.error('物品库存不足，无法出库')
        this.resetTime(true)
      } else {
        // 入库
        // 检查入库物品是否有新增
        const someNew = list.some(i => !i.goodsId && /0/.test(i.isPut))
        if (someNew) return $message.error(`${stockType}物品中有新物品，请点击操作`)
        $confirm({
          centered: true,
          maskClosable: true,
          title: '提示',
          content: `确定${$get(orderData, 'stockType', '入库')}?`,
          onOk () { submit() }
        })
      }
    },

    resetTime (show = false) {
      this.showSetTime = show
      this.range.splice(0)
    },

    async submit () {
      const { $axios, id, orderData, $message, $get, goback, list, range, resetTime } = this
      const { stockType } = orderData
      if (!stockType || this.sending) return $message.error('缺少库存类型，请刷新或稍后再试')
      this.$toggleSending(1)
      const url = stockType === '出库' ? 'out' : 'in'
      if (stockType === '出库' && (!range[0] || !range[1])) {
        this.$toggleSending()
        return $message.error('请设置物品领取时段')
      }
      const extendUrl = stockType === '出库' ? `/${range[0].format('YYYY-MM-DD')} 00:00:00/${range[1].format('YYYY-MM-DD')} 23:59:59` : ''

      const param = list.map(i => {
        const { id, goodsId, effectiveTime = '', actualQuantity, quantity } = i
        const data = { id, goodsId }
        if (stockType === '出库') data.actualQuantity = actualQuantity
        else data.quantity = quantity
        if (effectiveTime) data.effectiveTime = effectiveTime
        return data
      })
      const res = await $axios.put(`api/assetsApply/${url}/${id}${extendUrl}`, param).then(res => res).catch(e => false)
      $message.destroy()
      if ($get(res, 'data.code') !== '000000') {
        this.$toggleSending()
        return $message.error($get(res, 'data.mesg', '请稍后再试'))
      }
      resetTime()
      $message.info('操作成功')
      goback()
      const self = this
      setTimeout(() => self.$toggleSending(), 300)
    },

    goback () {
      this.$router.back()
    },

    handleSave (item) {
      const { $message, tempNum, $refs } = this
      if (tempNum > item.stockQty) {
        const inputDom = $refs.outQtyInput
        inputDom && inputDom.focus()
        $message.destroy()
        $message.error('出仓数不能大于库存数')
        return
      }
      Object.assign(item, { actualQuantity: tempNum })
      this.$forceUpdate()
      this.handleCancel(item)
    },

    handleCancel (item) {
      Object.assign(item, { editable: false })
      this.$forceUpdate()
      this.$nextTick(_ => {
        this.tempNum = 0
      })
    },

    handleEdit (item) {
      this.tempNum = item.actualQuantity
      Object.assign(item, { editable: true })
      this.$forceUpdate()
    },

    checkPDF ({ id, applyType, sn, status }) {
      if (id === -1) return false

      this.modalTitle = applyType
      this.modalText = `${applyType.replace('单', '')}状态：${statusMaps[status]}`
      this.url = ''
      this.fileName = ''

      this.$toggleSending(1)
      this.$axios({
        url: `api/assetsApply/down/${id}`,
        responseType: 'arraybuffer',
        method: 'get',
        contentType: 'application/pdf;charset=utf-8'
      }).then(res => {
        if (!res.data.code) {
          const blob = new Blob([res.data], { type: 'application/pdf;charset=utf-8' })
          this.url = window.URL.createObjectURL(blob)
          this.fileName = `${applyType}_${sn}_${Date.now()}`
          this.showPDF = true
          this.$toggleSending()
        }
      }).catch(e => [])
    }
  }
}
</script>

<style lang="less" scoped>
.filter {
  .header-container {
    .Flex;
    .Flex-align-center;
    .Flex-wrap;

    /deep/ .ant-row.ant-form-item {
      border: 1px solid rgba(211, 211, 211, .45);
      background: rgba(211, 211, 211, .15);
      padding-left: 12px;
      margin-right: 0 !important;
      margin-bottom: 0 !important;

      /deep/ .ant-form-item-children {
        height: 40px;
      }
    }

    .primary-link {
      padding-left: 0;
    }
  }
}

.table-container {
  white-space: normal;
  margin-bottom: 12px;
}

.button-container {
  text-align: center;
  width: 100%;
  margin: 20px auto;
}

.success-color {
  color: @green-7;
}

.primary-color {
  color: @blue-6;
}

.alarm-color {
  color: @red-6;
}

.match-item-container {
  .Flex;
  .Flex-center;

  .item-label {
    display: inline-block;
  }

  .item-cascader {
    .Flex-1;
  }
}
</style>
